// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_OUTPUT_COPY_OUTPUT_REQUEST_H_
#define CC_OUTPUT_COPY_OUTPUT_REQUEST_H_

#include <memory>

#include "base/callback.h"
#include "base/memory/ptr_util.h"
#include "cc/base/cc_export.h"
#include "cc/resources/single_release_callback.h"
#include "cc/resources/texture_mailbox.h"
#include "ui/gfx/geometry/rect.h"

class SkBitmap;

namespace cc {
class CopyOutputResult;

class CC_EXPORT CopyOutputRequest {
public:
    typedef base::Callback<void(std::unique_ptr<CopyOutputResult> result)>
        CopyOutputRequestCallback;

    static std::unique_ptr<CopyOutputRequest> CreateEmptyRequest()
    {
        return base::WrapUnique(new CopyOutputRequest);
    }
    static std::unique_ptr<CopyOutputRequest> CreateRequest(
        const CopyOutputRequestCallback& result_callback)
    {
        return base::WrapUnique(new CopyOutputRequest(false, result_callback));
    }
    static std::unique_ptr<CopyOutputRequest> CreateBitmapRequest(
        const CopyOutputRequestCallback& result_callback)
    {
        return base::WrapUnique(new CopyOutputRequest(true, result_callback));
    }
    static std::unique_ptr<CopyOutputRequest> CreateRelayRequest(
        const CopyOutputRequest& original_request,
        const CopyOutputRequestCallback& result_callback);

    ~CopyOutputRequest();

    bool IsEmpty() const { return result_callback_.is_null(); }

    // Optionally specify the source of this copy request.  If set when this copy
    // request is submitted to a layer, a prior uncommitted copy request from the
    // same |source| will be aborted.
    void set_source(void* source) { source_ = source; }
    void* source() const { return source_; }

    bool force_bitmap_result() const { return force_bitmap_result_; }

    // By default copy requests copy the entire layer's subtree output. If an
    // area is given, then the intersection of this rect (in layer space) with
    // the layer's subtree output will be returned.
    void set_area(const gfx::Rect& area)
    {
        has_area_ = true;
        area_ = area;
    }
    bool has_area() const { return has_area_; }
    gfx::Rect area() const { return area_; }

    // By default copy requests create a new TextureMailbox to return contents
    // in. This allows a client to provide a TextureMailbox, and the compositor
    // will place the result inside the TextureMailbox.
    void SetTextureMailbox(const TextureMailbox& texture_mailbox);
    bool has_texture_mailbox() const { return has_texture_mailbox_; }
    const TextureMailbox& texture_mailbox() const { return texture_mailbox_; }

    void SendEmptyResult();
    void SendBitmapResult(std::unique_ptr<SkBitmap> bitmap);
    void SendTextureResult(
        const gfx::Size& size,
        const TextureMailbox& texture_mailbox,
        std::unique_ptr<SingleReleaseCallback> release_callback);

    void SendResult(std::unique_ptr<CopyOutputResult> result);

private:
    CopyOutputRequest();
    CopyOutputRequest(bool force_bitmap_result,
        const CopyOutputRequestCallback& result_callback);

    void* source_;
    bool force_bitmap_result_;
    bool has_area_;
    bool has_texture_mailbox_;
    gfx::Rect area_;
    TextureMailbox texture_mailbox_;
    CopyOutputRequestCallback result_callback_;
};

} // namespace cc

#endif // CC_OUTPUT_COPY_OUTPUT_REQUEST_H_
